package implementation.server;


import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.logging.Logger;


import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.ChannelGroupFuture;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;


public class ServerConnectionManager implements IServerConnectionManager {
	
	public static final long TIMEOUT = 2000;
	
	private Logger _logger = Logger.getLogger(ServerConnectionManager.class.getName());

	private ChannelGroup _channels = new DefaultChannelGroup(ServerConnectionManager.class.getName());
	
	private ServerBootstrap _bootstrap;
	
	private final ISessionManager _sessionManager;
	
	public ServerConnectionManager(ISessionManager sessionManager) {
		
		this._sessionManager = sessionManager;
		
		ChannelFactory factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
		
		this._bootstrap = new ServerBootstrap(factory);
		
		this._bootstrap.setPipelineFactory(new ServerPipelineFactory(this._channels, this._sessionManager));
		
		this._bootstrap.setOption("child.tcpNoDelay", true);
		this._bootstrap.setOption("child.keepAlive", true);
	}
	

	@Override
	public boolean start(int port) {
		try {
			Channel channel = this._bootstrap.bind(new InetSocketAddress("localhost",port));
			this._channels.add(channel);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	@Override
	public void close() {
		ChannelGroupFuture future = _channels.close();
		future.awaitUninterruptibly(ServerConnectionManager.TIMEOUT);
		this._bootstrap.releaseExternalResources();
	}
	
}
